//#define CXXOMFORT_NOTICES 1
#include <cxxomfort/base.hpp>
#include <cxxomfort/library/fixed_vector.hpp>
#include <cxxomfort/algorithm.hpp>
#include <cxxomfort/random.hpp>
#include <cxxomfort/library/random.hpp>
#include <cxxomfort/library/type_name.hpp>
#include <cxxomfort/ostream.hpp>
//#include <cxxomfort/impl/07-ranlux.hpp>
#include <memory>
#include <cstdio>
#include <string>
#include <iostream>
#include <numeric>

namespace cxl= cxxomfort::library;
const uint32_t SZ= 100;
namespace cxlrandom= cxxomfort::library::random;

template <typename T, T l, T h>
struct BoundedInt {
	T value;
	CXXO_CONSTEXPR14
	explicit BoundedInt (T x) 
	: value() {
		assert (std::clamp(x,l,h)==x);
	}
	
	operator T () const { return value; }
	
	
};


struct avg_accumulate {
	double Sum;
	size_t N;
	avg_accumulate () 
	: Sum(0), N(0) 
	{ }

	double avg () const {
		return Sum/(double)N;
	}

	template <typename T>
	avg_accumulate&  operator+ (T t) {
		Sum+= t;
		N+= 1;
		using namespace std;
		printf("%6lu : %f %f\n" , N, Sum, avg());
		return *this;
	}
	
};

int main () {
    using namespace std;
    using cxxomfort::library::fixed_vector;
    fixed_vector<uint32_t> L(SZ);
    typedef ranlux24_base RNG;
    RNG R(time(0));
    for (int i=0; i < 100; ++i) { cout<< "R "<< R()<< endl; }
    generate(begin(L), end(L), R);
    //CXXO_FOREACH(uint32_t u, L) { cout<< u<< " \t"; }
    cout<< endl;
    double A = accumulate(begin(L), end(L), avg_accumulate() ).avg();
    cout<< "avg "<< A<< endl;
    cout<< cxxomfort::library::type_name<RNG>()<< endl;
    
}
